學習 React 的過程中,常常會碰到各種與「渲染」相關的名詞與概念,尤其在試圖理解「React 如何與瀏覽器互動」以及「各種不同渲染術語」時,總覺得有點卡卡的,今天這篇會試著從不同角度整理出這些概念。
瀏覽器的渲染過程
圖片來源 https://gist.github.com/faressoft
認識Reflow和Repaint 這篇講的很清楚,有提到簡單來說:
需要重新計算DOM節點 → Reflow
更改樣式重新繪製畫面,不涉及畫面排版→ Repaint
在 React 中,如何思考 Repaint 與 Reflow?
useMemo
與 useCallback
的使用、Concurrent Mode 等。客戶端渲染(CSR, Client-Side Rendering):
所有的 JavaScript 和 HTML 在一開始都是由瀏覽器下載,然後由 JavaScript 執行來生成畫面,像是典型的 SPA 應用程式。好處是使用者操作會很流暢,缺點是初次載入的時間較長,SEO 也不太好。
伺服器端渲染(SSR, Server-Side Rendering):
頁面一開始由伺服器生成完整的 HTML,再送到客戶端。當使用者請求一個頁面時,伺服器先執行 React 程式碼來組合出 HTML 結構並發送,這樣頁面在瀏覽器中能更快看到完整內容。它解決了 CSR 的 SEO 問題,但每次請求都會消耗伺服器資源。
靜態網站生成(SSG, Static Site Generation):
在 build 時(編譯階段)預先生成所有 HTML 靜態頁面,並且部署到 CDN 上。這樣的做法讓網站有最快的載入速度,適合用在內容不常變動的網站上(像是部落格或文檔)。但如果頁面內容需要頻繁更新,靜態生成就不太合適了。
靜態渲染和動態渲染之間的差異,在於頁面內容是「固定的」還是「根據需求變動的」。
如何區分靜態渲染與動態渲染?
這取決於頁面的內容是否需要動態更新。例如,顯示商品列表的頁面,如果使用 SSG 生成靜態頁面,那麼所有訪客看到的都是相同的內容(靜態渲染)。而若使用 SSR 或 CSR,頁面內容則可能根據使用者的互動或資料狀態變動(動態渲染)。
如何在 React 中理解這些術語?
理解這些術語的核心在於理解渲染的時機和位置。例如,Rehydration 更多的是在 CSR 和 SSR 結合的情境下出現,而 Prerendering 則是在靜態頁面的優化策略中使用。知道它們的存在,有助於你更好地選擇適合專案需求的渲染策略。
搞懂這些概念最困難的部分,在於它們有時會交錯使用。例如,靜態渲染可以用在 SSG 的情境中,而 SSR 則屬於 動態渲染 的一種情況。以下是一個整理圖,幫助你更好地理解這些概念之間的連結:
渲染類型 | 生成時間 | 生成位置 | 例子 |
---|---|---|---|
CSR | 使用者請求時 | 客戶端(瀏覽器) | React SPA |
SSR | 使用者請求時 | 伺服器 | Next.js 的 getServerSideProps 或是 server component |
SSG | 部署(或建置)時 | 伺服器 | Gatsby、Next.js 的靜態生成 |
靜態渲染 | 部署(或建置)時 | 伺服器 | Gatsby、Hexo 靜態頁面 |
動態渲染 | 使用者請求時 | 伺服器 | PHP、Node.js |